<template>
  <div class="fast_body">
    <div class="fast_header">
      <h1>证书制作</h1>
      <el-tooltip :open-delay="2000" effect="light" content="保存" placement="top">
        <i @click="save" class="save_icon iconfont icon-save1"></i>
      </el-tooltip>
    </div>
    <div class="fast_container">
      <div class="tools">
        <div class="tools_slide">
          <div class="slide_item" @click="addTextItem">
            <i class="iconfont icon-text slide_icon"></i>
            <span class="slide_text">文字</span>
          </div>
          <div class="slide_item" @click="preview">
            <i class="iconfont icon-preview1 slide_icon"></i>
            <span class="slide_text">预览</span>
          </div>
        </div>
        <!-- <div class="tools_list"></div> -->
      </div>
      <div class="boards" @mouseover="isInBoards = true" @mouseout="isInBoards=false">
        <div class="boards_container" @click="bodyClick($event)">
          <div
            :style="{
                overflow:'auto',
            width:scale>100?scale+'%':'100%',
            height:scale>100?scale+'%':'100%'
        }
        "
          >
            <div
              class="boards_box p-event"
              v-if="updateFlag"
              :style="{
              width:(config.width?config.width:600)+'px',height:(config.height?config.height:300)+'px',backgroundColor:config.backgroundColor,transform:'scale('+(scale/100)+')',
          }"
            >
              <div class="boards_bg" v-if="config.backgroundImage">
                <img :src="config.backgroundImage" alt />
              </div>
              <template v-for="(item, index) in config.children">
                <vue-draggable-resizable
                  class-name="boards_item vdr"
                  class-name-resizable="boards_item resizing"
                  class-name-dragging="boards_item dragging "
                  class-name-handle="boards_item handle"
                  :x="item.x"
                  :z="99"
                  :y="item.y"
                  :active="index==activeItem"
                  :prevent-deactivation="true"
                  :minHeight="30"
                  :minWidth="30"
                  :key="index"
                  :parent="true"
                  :left="0"
                  :w="item.width"
                  :h="item.height"
                  @activated=" selectItem(index) "
                  @dragging="onDrag"
                  @resizing="onResize"
                >
                  <p
                    class="boards_item"
                    :style="{ fontSize: item.fontSize+'px', color: item.color ,lineHeight:1,fontFamily:item.fontFamily|| '微软雅黑'}"
                  >{{ item.default }}</p>
                </vue-draggable-resizable>
              </template>
            </div>
          </div>
        </div>
      </div>
      <div class="options">
        <div class="tabs">
          <div class="tab_item" @click="tabActive=0" :class="{'active':tabActive===0}">属性设置</div>
          <div @click="tabActive=1" :class="{'active':tabActive===1}" class="tab_item">证书设置</div>
        </div>
        <div class="certificate_option params_option" v-show="tabActive===0">
          <el-form
            v-if="activeItem != null"
            label-width="60px"
            :model="config.children[activeItem]"
            size="small"
          >
            <el-form-item label="名称">
              <el-input placeholder="请输入" v-model="config.children[activeItem].name"></el-input>
            </el-form-item>
            <el-row>
              <el-col :span="12">
                <el-form-item label="宽">
                  <el-input
                    type="number"
                    oninput="if(value<0)value=0"
                    :min="0"
                    placeholder="请输入"
                    v-model="config.children[activeItem].width"
                  ></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label-width="60px" label-position="top" label="高">
                  <el-input
                    type="number"
                    oninput="if(value<0)value=0"
                    :min="0"
                    placeholder="请输入"
                    v-model="config.children[activeItem].height"
                  ></el-input>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="12">
                <el-form-item label="X">
                  <el-input
                    type="number"
                    oninput="if(value<0)value=0"
                    :min="0"
                    placeholder="请输入"
                    v-model="config.children[activeItem].x"
                  ></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="Y">
                  <el-input
                    type="number"
                    oninput="if(value<0)value=0"
                    :min="0"
                    placeholder="请输入"
                    v-model="config.children[activeItem].y"
                  ></el-input>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="16">
                <el-form-item label="字体">
                  <el-select v-model="config.children[activeItem].fontFamily" placeholder="请选择">
                    <el-option
                      v-for="(item,index) in fontList"
                      :key="index"
                      :label="item"
                      :value="item"
                    ></el-option>
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label-width="15px">
                  <el-color-picker v-model="config.children[activeItem].color"></el-color-picker>
                </el-form-item>
              </el-col>
            </el-row>
            <el-form-item label="字号">
              <el-select
                style="width:85px"
                v-model="config.children[activeItem].fontSize"
                placeholder="请选择"
              >
                <el-option
                  v-show="item>=8"
                  v-for="item in 100"
                  :key="item"
                  :label="item"
                  :value="item"
                ></el-option>
              </el-select>
              <el-input
                style="width:85px;marginLeft:10px"
                type="number"
                oninput="if(value<0)value=0"
                :min="8"
                :max="100"
                placeholder="请输入"
                v-model="config.children[activeItem].fontSize"
              ></el-input>
            </el-form-item>
            <el-form-item label="参数">
              <el-input
                oninput="value=value.replace(/[^\w\.\/]/ig,'')"
                placeholder="请输入"
                v-model="config.children[activeItem].params"
              ></el-input>
            </el-form-item>
            <el-form-item label="默认">
              <el-input
                :rows="5"
                resize="none"
                type="textarea"
                placeholder="请输入"
                v-model="config.children[activeItem].default"
              ></el-input>
            </el-form-item>
            <el-form-item label="备注">
              <el-input placeholder="请输入" v-model="config.children[activeItem].remark"></el-input>
            </el-form-item>
          </el-form>
          <div class="no_data" v-show="activeItem == null">
            <img class="no_data_icon" src="./newNoData.png" alt />
            <div class="no_data_tip">请点击选择要设置的元素</div>
          </div>
        </div>
        <div class="certificate_option" v-show="tabActive===1">
          <el-form label-width="60px" :model="config" size="small">
            <el-form-item label="名称">
              <el-input placeholder="请输入" v-model="config.name"></el-input>
            </el-form-item>
            <el-form-item label="宽度">
              <el-input
                @blur="forceUpdate"
                type="number"
                oninput="if(value<0)value=0"
                :min="0"
                placeholder="请输入"
                v-model="config.width"
              ></el-input>
            </el-form-item>
            <el-form-item label="高度">
              <el-input
                type="number"
                @blur="forceUpdate"
                oninput="if(value<0)value=0"
                :min="0"
                placeholder="请输入"
                v-model="config.height"
              ></el-input>
            </el-form-item>
            <el-form-item label="背景色">
              <el-color-picker v-model="config.backgroundColor"></el-color-picker>
            </el-form-item>
            <el-form-item label="背景图">
              <div class="upload_row">
                <el-upload
                  class="upload-demo"
                  action="/api/institutionEnter/uploadFile"
                  :on-success="handleSuccess"
                  :show-file-list="false"
                >
                  <el-button icon="el-icon-upload" size="small" type="primary">上传</el-button>
                  <!-- <div slot="tip" class="el-upload__tip">只能上传jpg/png文件，且不超过500kb</div> -->
                </el-upload>
                <el-button
                  @click="handleRemove"
                  v-show="config.backgroundImage"
                  style="marginLeft:10px"
                  size="small"
                  type="primary"
                >删除背景图</el-button>
              </div>
            </el-form-item>
          </el-form>
        </div>
      </div>
      <div class="scale_box">
        <div class="item scale-area">
          <i @click="scaleShort" title="缩小" class="icon iconfont icon-minus"></i>
          <p class="scale-num">{{scale}}%</p>
          <i title="放大" @click="scaleAdd" class="icon iconfont icon-plus"></i>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
/* 
证书生成器：
    核心技术：
    1. vue-draggable-resizable 拖拽面板，
    2. 组件化样式配置
    3. html2canvas 完成截图
*/
import wangEditor from "./wangEditor.vue";
import html2canvas from "html2canvas";
import $ from "jquery";
import domtoimage from "dom-to-image";
import { api as viewerApi } from "v-viewer";
export default {
  name: "",
  props: {},
  components: { wangEditor },
  data() {
    return {
      isInBoards: false, // 鼠标是否在面板内
      config: {
        name: "默认名称",
        width: 780,
        height: 1080,
        backgroundColor: "#fff",
        backgroundImage: null,
        children: [],
      },
      currentParams: {
        type: "text",
        x: 30,
        y: 30,
        width: 200,
        height: 200,
        color: "#000",
        fontSize: 16,
        name: "",
        remark: "",
        default: "张三",
      },
      currentParamsIndex: 0,
      tabActive: 0,
      activeItem: null,
      updateFlag: true,
      scale: 100,
      previewImgSrc: "",
      fontList: [
        "微软雅黑",
        "汉仪尚巍手书",
        "方正仿宋简体",
        "南宋书局体",
        "创艺简标宋",
        "方正楷体简体",
      ],
    };
  },
  computed: {},
  created() {},
  mounted() {
    // 监听键盘删除事件，删除元素
    document.addEventListener("keydown", this.keyEvent);
  },
  methods: {

    // 下载
    save() {
      domtoimage
        .toPng(document.querySelector(".boards_box"))
        .then(function (dataUrl) {
          var link = document.createElement("a");
          link.download = "1.png";
          link.href = dataUrl;
          link.click();
        })
        .catch(function (error) {
          console.error("oops, something went wrong!", error);
        });
    },
    // 预览
    preview() {
      html2canvas(document.querySelector(".boards_box"), {
        useCORS: true,
        allowTaint: true,
      }).then((canvas) => {
        const imgUrl = canvas.toDataURL("image/jpeg");
        this.previewImgSrc = imgUrl;
        this.showPre();
        // const image = document.createElement("img");
        // image.src = imgUrl;
        // // 将生成的图片放到 类名为 content 的元素中
        // // document.querySelector(".content").appendChild(image);
        // const a = document.createElement("a");
        // a.href = imgUrl;
        // // a.download 后面的内容为自定义图片的名称
        // a.download = "测试证书";
        // a.click();
      });
    },

    showPre() {
      const $viewer = this.$viewerApi({
        images: [this.previewImgSrc],
      });
    },
    
    handleSuccess(res, file) {
      this.config.backgroundImage = res.data.url;
    },
    handleRemove() {
      this.config.backgroundImage = "";
    },
    // 点击事件清除选中状态
    bodyClick(e) {
      if (e.target.className.indexOf("boards_item") == -1) {
        this.activeItem = null;
      } else {
        return;
      }
    },
    // 组件缩放
    onResize: function (x, y, width, height) {
      this.config.children[this.activeItem].x = x;
      this.config.children[this.activeItem].y = y;
      this.config.children[this.activeItem].width = width;
      this.config.children[this.activeItem].height = height;
    },
    // 组件拖拽
    onDrag: function (x, y) {
      this.config.children[this.activeItem].x = x;
      this.config.children[this.activeItem].y = y;
    },
    // 选中事件
    selectItem(index) {
      this.activeItem = index;
      this.tabActive = 0;
    },
   // 面板数据变更强制重新渲染面板
    forceUpdate() {
      this.updateFlag = false;
      this.$nextTick(() => {
        this.updateFlag = true;
      });
    },
    // 缩放
    scaleShort() {
      if (this.scale > 25) {
        this.scale -= 25;
      }
    },
    scaleAdd() {
      this.scale += 25;
    },
    // 添加组件
    addTextItem() {
      this.config.children.push({
        type: "text",
        x: 30,
        y: 30,
        width: 200,
        height: 30,
        color: "#000",
        fontSize: 16,
        name: "默认名称",
        remark: "",
        default: "默认文本",
        fontFamily: "微软雅黑",
        params: "",
      });
    },
    keyEvent(event) {
      if (
        (event.key == "Backspace" ||
          event.key == "Delete" ||
          event.keyCode == 8 ||
          event.keyCode == 46) &&
        this.isInBoards === true
      ) {
        this.deleteItem();
      }
    },
     // 删除组件
    deleteItem() {
      if (this.activeItem != null) {
        this.config.children.splice(this.activeItem, 1);
        this.activeItem = null;
      }
    },
  },
  beforeDestroy() {
    document.removeEventListener("keydown", this.keyEvent);
  },
  watch: {},
  filters: {},
};
</script>

<style scoped lang='scss'>
.vdr {
  border: none;
}
.handle,
.active.vdr {
  border: 1px dashed #000;
}
.fast_body {
  width: 100%;
  height: 100vh;
  line-height: 1;
  display: flex;
  overflow: hidden;
  color: #333;
  flex-direction: column;
  .fast_header {
    border-bottom: 1px solid #f1f3f7;
    box-shadow: 0 6px 4px -4px rgba(30, 30, 30, 0.1),
      8px 0 6px -6px rgba(50, 50, 50, 0.1);
    padding: 20px;
    display: flex;
    align-items: center;
    .save_icon {
      font-size: 20px;
      cursor: pointer;
      margin-left: 20px;
    }
  }
  .fast_container {
    height: 0;
    flex: 1;
    display: flex;
    width: 100%;
  }
}
.tools {
  display: flex;
  height: 100%;
  .tools_slide {
    width: 80px;
    height: 100%;
    border-right: 1px solid #f1f3f7;
    padding: 20px 0;
    .slide_item {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      margin-bottom: 20px;
      cursor: pointer;
      .slide_icon {
        font-size: 24px;
      }

      .slide_text {
        font-size: 14px;
        margin-top: 10px;
      }
    }
    .slide_item:hover {
      color: #2c8ef8;
    }
    > .slide_item:last-child {
      margin-bottom: 0;
    }
  }
  .tools_list {
    width: 328px;
    height: 100%;
  }
}
.boards {
  flex: 1;
  width: 0;
  height: 100%;
  overflow: hidden;
  background-color: #f1f3f7;
  position: relative;
  .boards_container {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    overflow: auto;
    .boards_box {
      margin: 30px auto;
      position: relative;
      background-size: 100% 100%;
      background-repeat: no-repeat;
      transform-origin: center top;
      .boards_bg {
        position: absolute;
        width: 100%;
        height: 100%;
        left: 0;
        top: 0;
        z-index: 20;
        img {
          width: 100%;
          height: 100%;
        }
      }
    }
  }
}
.options {
  width: 300px;
  height: 100%;
  padding: 0 10px;
  display: flex;
  flex-direction: column;
  .tabs {
    display: flex;
    border-bottom: 1px solid #e4e9ee;
    .tab_item {
      width: 50%;
      height: 60px;
      line-height: 60px;
      font-size: 16px;
      font-weight: 400;
      text-align: center;
      color: #333;
      cursor: pointer;
    }
    .active {
      position: relative;
    }
    .active::after {
      content: "";
      position: absolute;
      bottom: 5px;
      left: 50%;
      transform: translateX(-50%);
      width: 50%;
      height: 3px;
      background-color: #2c8ef8;
    }
  }
  .certificate_option {
    padding: 20px 0;
    flex: 1;
    height: 0;
    padding-right: 20px;
    overflow: auto;
  }
}
.upload_row {
  display: flex;
  align-items: center;
}
.no_data {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  margin: 40% auto;
  .no_data_icon {
    width: 120px;
    width: 128px;
  }
  .no_data_tip {
    margin-top: 15px;
    font-size: 14px;
    color: #909399;
  }
}
.scale_box {
  position: fixed;
  bottom: 30px;
  right: 350px;
  background-color: #fff;
  width: 120px;
  height: 36px;
  border-radius: 4px;
  color: #333;
  line-height: 36px;
  font-size: 12px;
  z-index: 99;
  -webkit-box-shadow: 0 6px 4px -4px rgba(30, 30, 30, 0.1),
    8px 0 6px -6px rgba(50, 50, 50, 0.1);
  box-shadow: 0 6px 4px -4px rgba(30, 30, 30, 0.1),
    8px 0 6px -6px rgba(50, 50, 50, 0.1);
  padding: 0 20px;
  .scale-area {
    display: flex;
    align-items: center;
    height: 36px;
    justify-content: space-between;
    font-size: 16px;
    i {
      font-size: 20px;
      cursor: pointer;
    }
  }
}
</style>